home *** CD-ROM | disk | FTP | other *** search
-
- /* Copyright (C) 2009 Norman Solomon
- * e-mail: historytree.addon@yahoo.com
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the License.
- */
-
- // ****************************************************************************
- // ***** *****
- // ***** TREE-VIEW FUNCTIONS THAT RESPOND TO AND PROCESS GUI EVENTS *****
- // ***** ---------------------------------------------------------- *****
- // ***** 1) Process user's mouse-clicks on TreeView gCanvas *****
- // ***** 2) Sets gTreeNode[] pointers for TreeView quick-views *****
- // ***** *****
- // ****************************************************************************
-
- // ==========================================================================
- // Called from canvasMouseClickEventHandler() in "historyViewer.js" - which
- // is in turn called from "historyViewer.xul" <html:canvas ...> onclick()
- // --------------------------------------------------------------------------
- // Does req process when the user clicks on a TreeNode box on the gCanvas
- // ==========================================================================
- function respondToTreeViewMouseClickOnCanvas(x, y)
- {
- // Get mouse click event info in Point(x,y) form
- // x = button click constant; y = index of TreeNode in gTreeNodes[]
- var clickResult = treeViewButtonFromMouseClick(x, y);
-
- // Get the button and TreeNode that the user clicked on
- var btnClicked = clickResult.x;
- var node = gTreeNodes[clickResult.y];
-
- // -----------------------------------------------------------
- // If an expanded image is currently visible clear it, then...
- if (gExpandedNode !== null)
- {
- // Exit if user clicks on SAME "?" button twice in succesion
- if (btnClicked === BTN_SHOW_IMAGE && node === gExpandedNode)
- {
- drawTree(false, null, null);
- return;
- }
-
- // Clear expanded image (sets gExpandedNode = null)
- drawTree(false, null, null);
-
- // Exit if user clicked on the image or root info box, because
- // clicks on buttons or nodes hidden BEHIND these are confusing
- if (x > gImgXY.x && x < gImgXY.x + gInfoBoxWH.x
- && y > gImgXY.y && y < gImgXY.y + gInfoBoxWH.y)
- {
- return;
- }
- }
-
- // -------------------------------------------------------------
- // Do req process if user clicked on drawn node box or button
- if (btnClicked === BTN_CHANGE_TREE)
- {
- // Expand or contract sub-tree
- showOrHideSubTreeForRoot(node);
- }
- else if (btnClicked === BTN_SHOW_IMAGE)
- {
- // Reset global flags that control image expansion
- gExpandedNode = node;
-
- // Expand node image or draw root node info box
- // *** ASSUMES that tree root node is in gTreeNodes[0]
- if (clickResult.y === 0)
- {
- gNodeImageWid = 0;
- drawSessInfoBox(node);
- }
- else
- {
- // Start setInterval() that produces image expansion *** NOTE
- // Some PC's have slow graphics - So uses 10 steps of 75 to 750
- gNodeImageWid = 75;
- gImgExpandInterval = setInterval
- (drawExpandingNodeImageOnCanvas, 18, node);
- }
- }
- else if (btnClicked === BTN_OPEN_PAGE)
- {
- // Open page in FF if user clicked on a TreeNode
- // "Dummy" Tree root in gTreeNodes[0] is ignored
- if (clickResult.y !== 0)
- openOrGotoSelectedHistoryPage(node);
- }
- }
-
- // ============================================================================
- // Called from respondToTreeViewMouseClickOnCanvas - Returns Point(x,y) where;
- // ----------------------------------------------------------------------------
- // x = Integer for button clicked (see global constants in "historyViewer.js")
- // y = The index in gTreeNodes[] of the TreeNode that the user clicked on
- // ============================================================================
- function treeViewButtonFromMouseClick(x, y)
- {
- var node;
- var halfBtnHgt = BOX_BTN_HGT / 2;
-
- // ---------------------------------------------------------------
- // Loop down gTreeNodes and find node clicked on (if any)
- // *** NOTE - The nested if() structure and added TreeNode props
- // are built for accurate, but above all, FAST click detection
- // ---------------------------------------------------------------
- for (var i = 0; i < gTreeNodes.length; i++)
- {
- // Get the TreeNode from gTreeNodes[]
- node = gTreeNodes[i];
-
- // Ignore hidden nodes
- if (!node.hidden)
- {
- // Check if user clicked anywhere on the overall node box
- if (x > node.pos.x
- && x < node.pos.x + node.width
- && y > node.pos.y
- && y < node.pos.y + node.height + halfBtnHgt)
- {
- // Check if user clicked on button panel at bottom of box
- if (x > node.btnPanelX
- && x < node.btnPanelX + node.btnPanelWid
- && y > node.pos.y + node.height - halfBtnHgt
- && y < node.pos.y + node.height + halfBtnHgt)
- {
- // User clicked somewhere on the node button panel
- // So return button clicked on and the TreeNode's index
- if (node.hidBtnWid > 0 && x < node.btnPanelX + node.hidBtnWid)
- {
- return new Point(BTN_CHANGE_TREE, i);
- }
- else
- {
- return new Point(BTN_SHOW_IMAGE, i);
- }
- }
-
- // User did not click on node button panel
- // So check if user clicked on the node itself
- if (y < node.pos.y + node.height)
- {
- // User clicked on the node - So return info
- return new Point(BTN_OPEN_PAGE, i);
- }
- }
- }
- }
-
- // ----------------------------------------------------
- // The user did NOT click on ANY node or node button
- return new Point(BTN_NONE, 0);
- }
-
- // ******************************************************************
- // ***** *****
- // ***** FUNCTIONS THAT SET TREE-VIEW QUICK-VIEW POINTERS *****
- // ***** -------------------------------------------------- *****
- // ***** Including expanding/contracting Tab root sub-tree's *****
- // ***** *****
- // ******************************************************************
-
- // ==========================================================
- // Restores all TreeNode pointers to their starting values
- // ==========================================================
- function restoreInitialTreePointers()
- {
- for (var i = 0; i < gTreeNodes.length; i++)
- {
- // Restore this TreeNode's pointers
- tNode = gTreeNodes[i];
- tNode.parent = tNode.parentBak;
- tNode.child = tNode.childBak;
- tNode.sibling = tNode.siblingBak;
-
- // Mark this TreeNode and its sub-tree as visible
- tNode.hidden = false;
- tNode.hiddenTreeSize = 0;
- tNode.childCopy = null;
- }
- }
-
- // ========================================================
- // Sets TreeNode pointers for "Show open tabs" quick-view
- // ========================================================
- function setTreePointersFor_OpenTabsQuickView()
- {
- var tabRoot, tabSibling;
- var numTabNodes = 0;
-
- // ---------------------------------------------
- // Restore initial tree state
- restoreInitialTreePointers();
-
- // Set req TreeNode props for all Tab root sub-tree's
- for (var i = 0; i < gTabRoots.length; i++)
- {
- // Get Tab root TreeNode object
- tabRoot = gTabRoots[i];
-
- // Cut off Tab root sibling if sibling is a closed Tab
- if (tabRoot.sibling !== null)
- {
- tabSibling = tabRoot.sibling;
- if (!tabSibling.inOpenTab)
- tabRoot.sibling = null;
- }
-
- // Process this Tab's sub-tree
- if (!tabRoot.inOpenTab)
- {
- // This Tab is closed - So hide it completely
- numTabNodes = markSubTreeAsHiddenOrVisible(tabRoot, true);
- }
- else
- {
- if (tabRoot.child === null)
- {
- // This open Tab has only one open page
- numTabNodes = 1;
- }
- else
- {
- // Get number of TreeNode's for this Tab (its already visible)
- numTabNodes = markSubTreeAsHiddenOrVisible(tabRoot, false);
- }
- }
-
- // Set number of TreeNode's for this Tab
- tabRoot.tabTreeSize = numTabNodes;
- }
- }
-
- // =========================================================
- // Sets TreeNode pointers for "Show open pages" quick-view
- // =========================================================
- function setTreePointersFor_OpenPagesQuickView()
- {
- var tabRoot, tabSibling;
- var chainParent, tNode, tSibling;
- var numTabNodes;
- var tabID;
-
- // ---------------------------------------------
- // Restore initial tree state
- restoreInitialTreePointers();
-
- // Cut off closed Tab siblings and hide all Tab sub-tree's
- for (var i = 0; i < gTabRoots.length; i++)
- {
- // Get Tab root TreeNode object
- tabRoot = gTabRoots[i];
-
- // Cut off Tab root sibling for closed Tabs
- if (tabRoot.sibling !== null)
- {
- tabSibling = tabRoot.sibling;
- if (!tabSibling.inOpenTab)
- tabRoot.sibling = null;
- }
-
- // Hide the Tab sub-tree completely
- markSubTreeAsHiddenOrVisible(tabRoot, true);
- }
-
- // ---------------------------------------------
- // Set open-page chain pointers for all Tabs
- for (var i = 0; i < gTabRoots.length; i++)
- {
- // Get Tab root TreeNode object
- tabRoot = gTabRoots[i];
-
- // Only process Tabs currently open in FF
- if (tabRoot.inOpenTab)
- {
- // Start the open-page chain for this Tab
- tabRoot.hidden = false;
- chainParent = tabRoot;
- tabID = chainParent.histNode.tab;
- numTabNodes = 1;
-
- // Set all open-page chain pointers for this Tab
- for (var ndx = 1; ndx < gTreeNodes.length; ndx++)
- {
- // Get Tab sub-tree TreeNode
- tNode = gTreeNodes[ndx];
-
- // Only process non-Tab-root TreeNode's for this Tab
- if (tNode.histNode.tab === tabID && tNode !== tabRoot)
- {
- // Nullify sibling (only Tab level siblings are shown)
- tNode.sibling = null;
-
- // Add to open-page chain if TreeNode is in that chain
- if (tNode.isOpenPage)
- {
- // Increment Tab TreeNode count
- numTabNodes ++;
-
- // Set chain pointers and make tNode visible
- chainParent.child = tNode;
- tNode.parent = chainParent;
- tNode.hidden = false;
-
- // Set this TreeNode as the next chain parent
- chainParent = tNode;
- }
- }
- }
-
- // Set number of TreeNode's for this Tab
- tabRoot.tabTreeSize = numTabNodes;
- }
- }
- }
-
- // ===========================================================
- // Sets TreeNode pointers for "Show selected tab" quick-view
- // ===========================================================
- function setTreePointersFor_SelectedTabQuickView(tabID)
- {
- var tabRoot, treeRoot;
- var numTabNodes;
-
- // ---------------------------------------------
- // Restore initial tree state
- restoreInitialTreePointers();
-
- // Set req TreeNode props for all Tab root sub-tree's
- for (var i = 0; i < gTabRoots.length; i++)
- {
- // Get Tab root TreeNode object
- tabRoot = gTabRoots[i];
-
- // Cut off ALL Tab root siblings
- tabRoot.sibling = null;
-
- // Set Tab sub-tree props
- if (tabRoot.histNode.tab === tabID)
- {
- // Make Tab root with req tabID the only child
- treeRoot = gTreeNodes[0];
- treeRoot.child = tabRoot;
-
- // Get number of TreeNode's for this Tab (its already visible)
- numTabNodes = markSubTreeAsHiddenOrVisible(tabRoot, false);
- }
- else
- {
- // Hide other Tabs completely
- numTabNodes = markSubTreeAsHiddenOrVisible(tabRoot, true);
- }
-
- // Set number of TreeNode's for this Tab
- tabRoot.tabTreeSize = numTabNodes;
- }
- }
-
- // ==========================================================
- // Sets TreeNode pointers for "Show closed tabs" quick-view
- // ==========================================================
- function setTreePointersFor_ClosedTabsQuickView()
- {
- var treeRoot, tabRoot, tabSibling;
- var firstClosedTab = null;
- var numTabNodes;
-
- // -------------------------------------------------
- // Restore initial tree state
- restoreInitialTreePointers();
-
- // Make treeRoot have no children (may be no closed Tabs)
- treeRoot = gTreeNodes[0];
- treeRoot.child = null;
-
- // --------------------------------------------------
- // Set req TreeNode props for all Tab root sub-tree's
- for (var i = 0; i < gTabRoots.length; i++)
- {
- // Get Tab root TreeNode object
- tabRoot = gTabRoots[i];
-
- // Cut off Tab root sibling for open Tabs
- if (tabRoot.sibling !== null)
- {
- tabSibling = tabRoot.sibling;
- if (tabSibling.inOpenTab)
- tabRoot.sibling = null;
- }
-
- // Make the treeRoot point to the first closed Tab
- if (!tabRoot.inOpenTab && firstClosedTab === null)
- {
- firstClosedTab = tabRoot;
- treeRoot.child = firstClosedTab;
- }
-
- // Process this Tab's sub-tree
- if (tabRoot.inOpenTab)
- {
- // Hide this open Tab completely
- numTabNodes = markSubTreeAsHiddenOrVisible(tabRoot, true);
- }
- else
- {
- if (tabRoot.child === null)
- {
- // This closed Tab has only one closed page
- numTabNodes = 1;
- }
- else
- {
- // Get number of TreeNode's for this Tab (its already visible)
- numTabNodes = markSubTreeAsHiddenOrVisible(tabRoot, false);
- }
- }
-
- // Set number of TreeNode's for this Tab
- tabRoot.tabTreeSize = numTabNodes;
- }
- }
-
- // =============================================================
- // Shows or hides sub-tree below root TreeNode user clicked on
- // Called from respondToTreeViewMouseClickOnCanvas(x, y)
- // =============================================================
- function showOrHideSubTreeForRoot(node)
- {
- if (node.childCopy === null && node.child !== null)
- {
- // Hide sub-tree
- hideSubTreeForRoot(node);
-
- // Show tree with sub-tree hidden
- drawTree(false, null, null);
- }
- else if (node.childCopy !== null)
- {
- // Make hidden sub-tree visible
- //alert("showing");
- node.hiddenTreeSize = 0;
- node.child = node.childCopy;
- node.childCopy = null;
- markSubTreeAsHiddenOrVisible(node, false);
-
- // Show tree with sub-tree made visible
- drawTree(false, null, null);
- }
- }
-
- // =========================================================
- // Hides the sub-tree that has the passed node as its root
- // =========================================================
- function hideSubTreeForRoot(node)
- {
- // Hide sub-tree
- var subTreeSize = markSubTreeAsHiddenOrVisible(node, true);
- node.hidden = false;
- node.hiddenTreeSize = subTreeSize;
- node.childCopy = node.child;
- node.child = null;
- }